--- /dev/null
+/*
+
+ Geogrid-Viewer overlay file Version 0.9.3
+
+ A detail description of the ASCII-overlay-fomat you can find in the
+ helpfile of Geogrid-Viewer.
+
+ Latest changes at 11.01.2005 by Fredie Kern
+
+ Copyright (C) 2005 Fredie Kern, f.kern@xdesy.de
+
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+#include "defs.h"
+#include "grtcirc.h"
+
+static void *mkshort_handle;
+
+#define MYNAME "overlay"
+#define PARAMETER_FILE "overlay.def"
+
+#undef MAPNAME
+#define MAPNAME "Bundesrepublik 1:1 Mio"
+#undef MAPNAME
+#define MAPNAME "Top. Karte 1:50.000 Nieders."
+
+static FILE *fpout;
+static FILE *fpin;
+static int govl_cnt;
+static double govl_sum_e=0.0;
+static double govl_sum_n=0.0;
+static double govl_sumcnt=0.0;
+static int govl_symbol_cnt=0;
+static int govl_group_cnt=0;
+/*
+static double govl_last_east=0.0;
+static double govl_last_north=0.0;
+*/
+
+static int govl_col=1;
+static char *govl_col_s = NULL;
+static int govl_size=101;
+static char *govl_size_s = NULL;
+static double govl_dir=0.0;
+
+static char *govl_mapname = NULL;
+static int govl_zoomfc = 100;
+static char *govl_zoomfc_s = NULL;
+static int govl_dimmfc = 100;
+static char *govl_dimmfc_s = NULL;
+
+
+static int govl_txtcol=1;
+static int govl_txtsize=120;
+static int govl_font=1;
+static int govl_txttrans=0;
+
+static char *govl_txtcol_s = NULL;
+static char *govl_txtsize_s = NULL;
+static char *govl_font_s = NULL;
+static char *govl_txttrans_s = NULL;
+
+static char *govl_file_s = NULL;
+
+static arglist_t ovl_args[] = {
+ { "col", &govl_col_s, "color index [1-9] for routes",
+ NULL, ARGTYPE_INT },
+ { "size", &govl_size_s, "size index [101-] for routes",
+ NULL, ARGTYPE_INT },
+ { "mapname", &govl_mapname, "name of map",
+ NULL, ARGTYPE_STRING },
+ { "zoomfc", &govl_zoomfc_s, "zoom factor of map in %",
+ NULL, ARGTYPE_INT },
+ { "dimmfc", &govl_dimmfc_s, "dimmer factor of map in %",
+ NULL, ARGTYPE_INT },
+ { "txtcol", &govl_txtcol_s, "color index [1-9] for waypoint names",
+ NULL, ARGTYPE_INT },
+ { "txtsize", &govl_txtsize_s, "text size [101-] for waypoint names",
+ NULL, ARGTYPE_INT },
+ { "font", &govl_font_s, "font index [1-] for waypoint names",
+ NULL, ARGTYPE_INT },
+ { "txttrans", &govl_txttrans_s, "set text background to transparent",
+ NULL, ARGTYPE_BOOL },
+ { "file", &govl_file_s, "use file of parameters (parameters on command line overwrites file parameters)",
+ NULL, ARGTYPE_STRING },
+ { 0, 0, 0, 0, 0 }
+};
+
+
+static char *Keywords[]={
+ "Typ",
+ "Group",
+ "Col",
+ "Zoom",
+ "Size",
+ "Art",
+ "Punkte",
+ "Path",
+ "Dir",
+ "Font",
+ "Area",
+ "Text",
+ "Width",
+ "Height",
+ "Trans",
+ "TransByte",
+ NULL
+ };
+
+#define KEY_TYP 0
+#define KEY_GROUP 1
+#define KEY_COL 2
+#define KEY_ZOOM 3
+#define KEY_SIZE 4
+#define KEY_ART 5
+#define KEY_PUNKTE 6
+#define KEY_PATH 7
+#define KEY_DIR 8
+#define KEY_FONT 9
+#define KEY_AREA 10
+#define KEY_TEXT 11
+#define KEY_WIDTH 12
+#define KEY_HEIGHT 13
+#define KEY_TRANS 14
+#define KEY_TRANSBYTE 15
+
+static int isKeyword(char *str,char **keys)
+{
+ int i;
+
+ i = 0;
+ while(keys[i]!=NULL && strcmp(str,keys[i])) i++;
+ return(keys[i]==NULL ? -1 : i);
+}
+
+/*----------------------------------------------*/
+
+void ovl_rd_init(char const *fname)
+{
+ fpin = xfopen(fname, "rt", MYNAME);
+}
+
+#define SECTION_NONE 0
+#define SECTION_SYMBOL 1
+#define SECTION_PUNKTE 2
+#define SECTION_OVERLAY 3
+
+#define MAXLINE 512
+
+static struct _group {
+ int group;
+ char *name;
+ } *groups;
+static int groups_cnt;
+
+void ovl_add_group(int aktgrp,char *akttxt)
+{
+ int i;
+
+ i = 0;
+ while (i<groups_cnt && groups[i].group!=aktgrp) i++;
+ if (i==groups_cnt)
+ {
+ groups = (struct _group *) xrealloc(groups,(groups_cnt+1)*sizeof(struct _group));
+ groups[i].group = aktgrp;
+ groups[i].name = NULL;
+ groups_cnt++;
+ }
+ groups[i].name = (char *) xrealloc(groups[i].name,(strlen(akttxt)+1)*sizeof(char));
+ strcpy(groups[i].name,akttxt);
+}
+
+/*
+ The name of route is stored in a 'Text'-symbol with identical 'Group'-number.
+*/
+void route_add_name(const route_head *hd)
+{
+ int grp;
+ int i;
+ char name[MAXLINE];
+ route_head *route;
+
+ route = (route_head *) hd;
+ grp = atoi(route->rte_name);
+ i = 0;
+ while (i<groups_cnt && groups[i].group!=grp) i++;
+ if (i==groups_cnt) // not found
+ {
+ sprintf(name,"undef(%d)",grp); /* pseudo name*/
+ sprintf(name,"?%d",grp);
+ }
+ else
+ {
+ strcpy(name,groups[i].name);
+ }
+ route->rte_name = (char *) xrealloc(route->rte_name,(strlen(name)+1)*sizeof(char));
+ strcpy(route->rte_name,name);
+}
+
+void ovl_read(void)
+{
+ char line[MAXLINE];
+ int isSection;
+ int aktTyp,aktCol,aktSize,aktArt,aktGroup;
+ int aktArea,aktWidth,aktHeight,aktTrans,aktTransByte,aktDir;
+ double aktX,aktY;
+ char *aktPath;
+ char *aktText;
+ char *pstr;
+ int keyw,i;
+ double rwert;
+ route_head *route_head;
+ waypoint *wpt;
+ int sym_cnt;
+
+ groups = NULL;
+ groups_cnt = 0;
+ aktTyp = aktCol = aktSize = aktArt = aktGroup = -1;
+ aktArea = aktWidth = aktHeight = aktTrans = aktTransByte = aktDir = -1;
+ aktX = aktY = 0.0;
+ aktText = NULL;
+ aktPath = NULL;
+ sym_cnt = 0;
+ isSection = SECTION_NONE;
+ while (fgets(line,MAXLINE-1,fpin)!=NULL)
+ {
+ if( (pstr = strstr(line,"[Symbol "))!= NULL)
+ {
+ sym_cnt++;
+ isSection = SECTION_SYMBOL;
+ }
+ else if( (pstr = strstr(line,"[Overlay]"))!= NULL)
+ {
+ isSection = SECTION_OVERLAY;
+ }
+ else if (isSection==SECTION_SYMBOL)
+ {
+ pstr = strtok(line,"=");
+ if (pstr!=NULL)
+ {
+ keyw = isKeyword(pstr,Keywords);
+ pstr = strtok(NULL,"\n");
+ if (pstr!=NULL)
+ {
+ switch(keyw)
+ {
+ case KEY_TYP :
+ aktTyp = atoi(pstr);
+ break;
+ case KEY_GROUP :
+ aktGroup = atoi(pstr);
+ ovl_add_group(aktGroup,"?"); /* 'Group' without relation to 'Text'-Symbol */
+ switch(aktTyp)
+ {
+ case 3: // Linie
+ route_head = route_head_alloc();
+ route_head->rte_num = sym_cnt;
+ route_head->rte_name = xstrdup(pstr); /* use group-number for the moment */
+ route_add_head(route_head);
+ break;
+ }
+ break;
+ case KEY_COL :
+ aktCol = atoi(pstr);
+ break;
+ case KEY_ZOOM :
+ break;
+ case KEY_SIZE :
+ aktSize = atoi(pstr);
+ break;
+ case KEY_ART :
+ aktArt = atoi(pstr);
+ break;
+ case KEY_AREA :
+ aktArea = atoi(pstr);
+ if (aktTyp==5 || aktTyp==5 || aktTyp==7) isSection = SECTION_PUNKTE; // Rechteck, Kreis, Dreieck
+ break;
+ case KEY_PUNKTE :
+ isSection = SECTION_PUNKTE; // Linie, Fläche
+ break;
+#ifdef WITH_BITMAP
+ case KEY_PATH :
+ aktPath = xstrdup(pstr);
+ isSection = SECTION_PUNKTE; // Bitmap
+ break;
+ case KEY_TRANS :
+ aktTrans = atoi(pstr);
+ break;
+ case KEY_TRANSBYTE :
+ aktTransByte = atoi(pstr);
+ break;
+#endif
+ case KEY_TEXT :
+ aktText = xstrdup(pstr);
+ /* The last 'Text'-symbol wins as a information block for
+ waypoint/route description.
+ Infos from previous symbols get overwrited.
+ */
+ ovl_add_group(aktGroup,aktText);
+ break;
+ case KEY_WIDTH :
+ aktWidth = atoi(pstr);
+ break;
+ case KEY_HEIGHT :
+ aktHeight = atoi(pstr);
+ break;
+ case KEY_DIR :
+ aktDir = atoi(pstr);
+ if (aktTyp==2) isSection = SECTION_PUNKTE; // Text
+ break;
+ }
+ }
+ }
+ }
+ else if (isSection==SECTION_PUNKTE)
+ {
+ pstr = strtok(line,"=");
+ if (strstr(pstr,"XKoord")!=NULL || strstr(pstr,"YKoord")!=NULL)
+ {
+ if ((pstr = strtok(NULL,"\n"))!=NULL)
+ {
+ rwert = atof(pstr);
+ if (line[0]=='X')
+ {
+ aktX = rwert;
+ }
+ else if (line[0]=='Y')
+ {
+ aktY = rwert;
+ switch(aktTyp)
+ {
+#ifdef WITH_BITMAP
+ case 1: // Bitmap
+ wpt = waypt_new();
+ wpt->latitude = aktY;
+ wpt->longitude = aktX;
+ wpt->altitude = 0.0;
+ wpt->shortname = strdup(aktPath);
+ waypt_add(wpt);
+ break;
+#endif
+ case 2: // Text
+ isSection = SECTION_SYMBOL;
+ break;
+ case 3: // Linie
+ wpt = waypt_new();
+ wpt->latitude = aktY;
+ wpt->longitude = aktX;
+ wpt->altitude = 0.0;
+ route_add_wpt(route_head, wpt);
+ break;
+ case 4: // Fläche
+ break;
+ case 5: // Rechteck
+ break;
+ case 6: // Kreis
+ break;
+ case 7: // Dreieck
+ break;
+ }
+ }
+ }
+ }
+ }
+ else if (isSection==SECTION_OVERLAY)
+ {
+ isSection = SECTION_NONE;
+ }
+ }
+ route_disp_all(route_add_name,NULL,NULL);
+ if (aktText!=NULL) xfree(aktText);
+ if (aktPath!=NULL) xfree(aktPath);
+ for (i=0;i<groups_cnt;i++)
+ {
+ if (groups[i].name!=NULL) xfree(groups[i].name);
+ }
+ xfree(groups);
+}
+
+void ovl_rd_deinit(void)
+{
+ fclose(fpin);
+}
+
+/*------------------------------------------*/
+void ovl_read_parameter(char *fname)
+{
+ FILE *fpin;
+ arglist_t *p;
+ char line[MAXLINE],str[MAXLINE];
+ char *pstr;
+
+ fpin = fopen(fname,"rt");
+ if (fpin!=NULL)
+ {
+ while (fgets(line,MAXLINE-1,fpin)!=NULL)
+ {
+ sscanf(line,"%s",str); // trim
+ if (str[0]!=';')
+ {
+ p = ovl_args;
+ pstr = strtok(line,"=");
+ if (pstr!=NULL)
+ {
+ while(p->argstring!=NULL)
+ {
+ if (strcmp(pstr,p->argstring)==0)
+ {
+ pstr = strtok(NULL,"\n");
+ if (p->argtype==ARGTYPE_BOOL)
+ {
+ *(p->argval) = atoi(pstr) ? strdup(pstr) : NULL;
+ }
+ else
+ {
+ *(p->argval) = strdup(pstr);
+ }
+ break;
+ }
+ p++;
+ }
+ }
+ }
+ }
+ fclose(fpin);
+ }
+}
+
+void ovl_wr_init(const char *fname)
+{
+ fpout = xfopen(fname, "wt", MYNAME);
+ govl_sum_n = 0.0;
+ govl_sum_e = 0.0;
+ govl_sumcnt = 0.0;
+ govl_symbol_cnt = 0;
+
+
+ ovl_read_parameter(govl_file_s!=NULL ? govl_file_s : PARAMETER_FILE);
+
+ if (govl_col_s!=NULL)
+ {
+ govl_col = atoi(govl_col_s);
+ }
+ if (govl_size_s!=NULL)
+ {
+ govl_size = atoi(govl_size_s);
+ }
+ if (govl_mapname==NULL)
+ {
+ govl_mapname = xstrdup(MAPNAME);
+ }
+ if (govl_zoomfc_s!=NULL)
+ {
+ govl_zoomfc = atoi(govl_zoomfc_s);
+ }
+ if (govl_dimmfc_s!=NULL)
+ {
+ govl_dimmfc = atoi(govl_dimmfc_s);
+ }
+ if (govl_txtcol_s!=NULL)
+ {
+ govl_txtcol = atoi(govl_txtcol_s);
+ }
+ if (govl_txtsize_s!=NULL)
+ {
+ govl_txtsize = atoi(govl_txtsize_s);
+ }
+ if (govl_font_s!=NULL)
+ {
+ govl_font = atoi(govl_font_s);
+ }
+ if (govl_txttrans_s!=NULL)
+ {
+ govl_txttrans = 1;
+ }
+}
+
+void ovl_wr_deinit(void)
+{
+ fprintf(fpout,"[Overlay]\n");
+ fprintf(fpout,"Symbols=%d\n",govl_symbol_cnt);
+ fprintf(fpout,"[MapLage]\n");
+ fprintf(fpout,"MapName=%s\n",govl_mapname);
+ fprintf(fpout,"DimmFc=%d\n",govl_dimmfc);
+ fprintf(fpout,"ZoomFc=%d\n",govl_zoomfc);
+ if (govl_symbol_cnt)
+ {
+ fprintf(fpout,"CenterLat=%.8lf\n",govl_sum_n/govl_sumcnt); // precision 8 = better than 1mm
+ fprintf(fpout,"CenterLong=%.8lf\n",govl_sum_e/govl_sumcnt);
+ }
+ else
+ {
+ fprintf(fpout,"CenterLong=10.52374295\n"); // Braunschweiger Löwe, Mittelpunkt der Welt :-)
+ fprintf(fpout,"CenterLat=52.26474445\n");
+ }
+ fprintf(fpout,"RefOn=0\n");
+
+ fclose(fpout);
+}
+
+void symbol_init(const route_head *hd)
+{
+ fprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
+ fprintf(fpout,"Typ=3\n"); // Linie
+ fprintf(fpout,"Group=%d\n" ,govl_group_cnt+1+1); // group==1 : not a group
+ fprintf(fpout,"Col=%d\n" ,govl_col);
+ fprintf(fpout,"Zoom=2\n");
+ fprintf(fpout,"Size=%d\n" ,govl_size);
+ fprintf(fpout,"Art=1\n");
+ fprintf(fpout,"Punkte=%d\n" ,hd->rte_waypt_ct);
+ govl_cnt = 0;
+ govl_symbol_cnt++;
+ govl_group_cnt++;
+}
+
+void symbol_text(double east,double north,char *text,int group)
+{
+ fprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
+ fprintf(fpout,"Typ=2\n"); // Text
+ fprintf(fpout,"Group=%d\n",group+1); // group==1 : not a group
+ fprintf(fpout,"Col=%d\n",govl_txtcol);
+ fprintf(fpout,"Area=%d\n",govl_txttrans ? 1 : 2); // =2 opak =1 transparent
+ fprintf(fpout,"Zoom=%d\n",2);
+ fprintf(fpout,"Size=%d\n",govl_txtsize);
+ fprintf(fpout,"Font=%d\n",govl_font);
+ fprintf(fpout,"Dir=%d\n",100+((int) govl_dir));
+ fprintf(fpout,"XKoord=%.8lf\n",east); // precision 8 = better than 1mm
+ fprintf(fpout,"YKoord=%.8lf\n",north);
+ fprintf(fpout,"Text=%s\n",text);
+ govl_symbol_cnt++;
+}
+
+void symbol_point(const waypoint *wpt)
+{
+ double east,north;
+
+ east = wpt->longitude;
+ north = wpt->latitude;
+ fprintf(fpout,"XKoord%d=%.8lf\n",govl_cnt,east); // precision 8 = better than 1mm
+ fprintf(fpout,"YKoord%d=%.8lf\n",govl_cnt,north);
+ govl_cnt++;
+ govl_sum_e += east;
+ govl_sum_n += north;
+ govl_sumcnt += 1.0;
+/*
+ govl_last_east = east;
+ govl_last_north = north;
+*/
+}
+
+
+void symbol_deinit(const route_head *hd)
+{
+ queue *elem, *tmp;
+ waypoint *waypointp;
+ int i;
+ double lat1, lon1, lat2, lon2;
+ double lats,lons,late,lone;
+ double dist,d,dd;
+
+ dist = 0.0;
+ i = 0;
+ QUEUE_FOR_EACH(&(hd->waypoint_list), elem, tmp)
+ {
+ waypointp = (waypoint *) elem;
+ lat2 = waypointp->latitude *M_PI/180.0 ;
+ lon2 = waypointp->longitude*M_PI/180.0 ;
+ if (i)
+ {
+ d = gcdist(lat1, lon1, lat2, lon2 );
+ dist += d;
+ }
+ else
+ {
+ lats = lat2; // start point
+ lons = lon2;
+ }
+ lat1 = lat2;
+ lon1 = lon2;
+ i++;
+ }
+ late = lat2; // end point
+ lone = lon2;
+ dd = 0;
+ i = 0;
+ elem = QUEUE_FIRST(&(hd->waypoint_list));
+ while (elem!=&(hd->waypoint_list) && dd<dist/2.0)
+ {
+ waypointp = (waypoint *) elem;
+ lat2 = waypointp->latitude *M_PI/180.0;
+ lon2 = waypointp->longitude*M_PI/180.0;
+ if (i)
+ {
+ d = gcdist(lat1, lon1, lat2, lon2 );
+ dd += d;
+ }
+ lat1 = lat2;
+ lon1 = lon2;
+ elem = QUEUE_NEXT(elem);
+ i++;
+ }
+
+ d = gcdist(lats,lons,late,lone);
+// d = acos( sin(lats)*sin(late)+cos(lats)*cos(late)*cos(lone-lons) );
+ dd = acos( (sin(late) - sin(lats)*cos(d))/(cos(lats)*sin(d)) );
+ if (lone<lons) dd = -dd; // correction because the ambiguity of acos function
+ dd = dd * 180.0/M_PI; // azimuth
+ dd = 360.0 - (dd + 270.0); // make it anticlockwise and start counting on x-axis
+ dd = dd < 0.0 ? dd + 360.0 : dd; // normalizing
+ dd = dd > 360.0 ? dd - 360.0 : dd; // normalizing
+
+ /* name of route */
+ /* plot text at the last point of route */
+ govl_dir = dd; // approximated text rotation, correct value must be the azimuth in UTM
+ symbol_text(lon1*180.0/M_PI,lat1*180.0/M_PI,hd->rte_name,govl_group_cnt);
+ govl_dir = 0.0; // restore
+}
+
+static void overlay_waypt_pr(const waypoint *waypointp)
+{
+ const char *oname;
+ char *odesc;
+
+ /*
+ * Desparation time, try very hard to get a good shortname
+ */
+ odesc = waypointp->notes;
+ if (!odesc) {
+ odesc = waypointp->description;
+ }
+ if (!odesc) {
+ odesc = waypointp->shortname;
+ }
+ oname = global_opts.synthesize_shortnames ?
+ mkshort(mkshort_handle, odesc) :
+ waypointp->shortname;
+
+ fprintf(fpout,"[Symbol %d]\n",govl_symbol_cnt+1);
+ fprintf(fpout,"Typ=1\n");
+ fprintf(fpout,"Group=1\n");
+ fprintf(fpout,"Width=100\n");
+ fprintf(fpout,"Height=100\n");
+ fprintf(fpout,"Dir=%d\n",100+((int) govl_dir));
+ fprintf(fpout,"Zoom=2\n");
+ fprintf(fpout,"Trans=2\n");
+ fprintf(fpout,"TransByte=5\n");
+ fprintf(fpout,"Path=%s\n","waypoint.bmp");
+ fprintf(fpout,"XKoord=%.8lf\n",waypointp->longitude);
+ fprintf(fpout,"YKoord=%.8lf\n",waypointp->latitude);
+ govl_symbol_cnt++;
+ govl_sum_e += waypointp->longitude;
+ govl_sum_n += waypointp->latitude;
+ govl_sumcnt += 1.0;
+
+}
+
+void ovl_write(void)
+{
+ waypt_disp_all(overlay_waypt_pr);
+ track_disp_all(symbol_init, symbol_deinit, symbol_point);
+ route_disp_all(symbol_init, symbol_deinit, symbol_point);
+/*
+ switch(global_opts.objective)
+ {
+ case wptdata:
+ break;
+ case trkdata:
+ break;
+ }
+*/
+}
+
+
+ff_vecs_t overlay_vecs = {
+ ff_type_internal,
+ FF_CAP_RW_ALL,
+ ovl_rd_init,
+ ovl_wr_init,
+ ovl_rd_deinit,
+ ovl_wr_deinit,
+ ovl_read,
+ ovl_write,
+ NULL,
+ ovl_args
+};